/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package graph;

import java.awt.Color;
import java.io.Serializable;
import java.util.ArrayList;

/**
 *
 * @author borysfan
 */
public class Graph implements Serializable {
    private static ArrayList<Node> nodes;
    private static Graph instance = null;
    private static int uniqId=0;

    public static Graph getInstance(){
        if(instance == null){
            instance = new Graph();
        }
        return instance;
    }

    public Graph(){
        nodes = new ArrayList<Node>();
    }

    public void addNode(Node n){
        if(exists(n)==false){
            n.setId(uniqId++);
            nodes.add(n);
            System.out.println("Graph. Wierzcholek " + n.getName()+" został dodany");
            //printGraph();
        }
    }

    public Edge addEdge(Node from,Node to){
        Edge e = new Edge(from,to);
        e.setId(uniqId++);
        from.addEdge(e);
        to.addEdge(e);
        printGraph();
        System.out.println("Graph. Krawedz od " + from.getName()+" do "+ to.getName() +" została dodana");
        System.out.println("Graph. Wierzcholek "+from.getName() + " ma " + from.getEdges().size() + "krawedzi wychodzacych.");
        System.out.println("Graph. Wierzcholek "+to.getName() + " ma " + to.getEdges().size() + "krawedzi wychodzacych.");
        return e;
    }

    public void clear(){
        nodes.clear();
        instance=new Graph();
       
    }

 
    public void removeNode(Node n){
        nodes.remove(n);
    }

    public Node getNode(int i){
        Node result = null;
        try{
           result = nodes.get(i);
        }catch( IndexOutOfBoundsException e){
            System.err.println("Graph.getNode(int) bound exception");
        }catch(Exception e){
            System.err.println("Graph.getNode(int) other error");
        }
        return result;
    }

    public ArrayList<Node> getNodes(){
        return nodes;
    }

    @Override
    public String toString(){
        String res=new String();
        for(int i=0;i<nodes.size();i++){
            System.out.println(nodes.get(i).getName());
            System.out.println(nodes.get(i));
            //res=nodes.get(i).toString()+"\n";
        }
        return res;
    }

    public void printGraph(){
        for(int i=0;i<this.nodes.size();i++){
            System.out.print(this.nodes.get(i).getName()+"("+nodes.get(i).getOnPath()+"): ");
            Node node = this.nodes.get(i);
            for(int j=0;j<node.getEdges().size();j++){
                System.out.print(node.getEdges().get(j).getEnd().getName());
            }
            System.out.print("\n");
        }
    }

    public Node findNodeByName(String s){
        for(int i=0;i<nodes.size();i++){
            if(nodes.get(i).getName().equals(s)){
                return nodes.get(i);
            }
        }
        return null;
    }

    public ArrayList<String> getEdgesNames(){
        ArrayList<String> result = new ArrayList<String>();
        for(int i=0;i<this.nodes.size();i++){
            result.add(new String(this.nodes.get(i).getName()));
        }
        return result;
    }

    public boolean exists(Node n){
        for(int i=0;i<nodes.size();i++){
            if(n.equals(nodes.get(i)))
                return true;
        }
        return false;
    }

    public Edge getEdge(Node from,Node to){
        System.out.println("Szukam krawedzi z "+from.getName()+" do "+to.getName());
        ArrayList<Edge> edges = from.getEdges();
        for(int i=0;i<edges.size();i++){
            Edge e = edges.get(i);
          //  System.out.println(e.getStart().getId() + " "+e.getEnd().getId() + " "+ from.getId() + " " + to.getId());
            if(((e.getStart().equals(from)==true) && (e.getEnd().equals(to)==true)) || ((e.getEnd().equals(from)==true) && (e.getStart().equals(to)==true)))
                return e;
        }
        return null;
    }

    public void setNodesColor(Color c){
        for(int i=0;i<nodes.size();i++){
            nodes.get(i).setColor(c);
        }
    }

    public void setEdgesColor(Color c){
        for(int i=0;i<nodes.size();i++){
            ArrayList<Edge> edgesList = nodes.get(i).getEdges();
            for(int j=0;j<edgesList.size();j++){
                edgesList.get(j).setColor(c);
            }
        }
    }

    public void setId(int size) {
        uniqId = size;
    }

    public int getWidth(){
       return Math.abs(getMaxX())+Math.abs(getMinX());
    }

    public int getHeight(){
        return Math.abs(getMaxY())+Math.abs(getMinY());
    }

    public int getMaxX(){
        int result = Integer.MIN_VALUE;
        for(int i=0;i<nodes.size();i++){
            if(nodes.get(i).getX()>result)
                result = nodes.get(i).getX();
        }
        return result;
    }

    public int getMinX(){
        int result = Integer.MAX_VALUE;
        for(int i=0;i<nodes.size();i++){
            if(nodes.get(i).getX()<result)
                result = nodes.get(i).getX();
        }
        return result;
    }

    public int getMaxY(){
        int result = Integer.MIN_VALUE;
        for(int i=0;i<nodes.size();i++){
            if(nodes.get(i).getY()>result)
                result = nodes.get(i).getY();
        }
        return result;
    }

    public int getMinY(){
        int result = Integer.MAX_VALUE;
        for(int i=0;i<nodes.size();i++){
            if(nodes.get(i).getY()<result)
                result = nodes.get(i).getY();
        }
        return result;
    }

    public int getId() {
        //uniqId++;
        return uniqId;
    }

    

}
